const Clutter = imports.gi.Clutter;
const Lang = imports.lang;
+const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
const Gtk = imports.gi.Gtk;
const Meta = imports.gi.Meta;
this._highlightDefault = false;
this._defaultResult = null;
+ this._startingSearch = false;
+
+ this._terms = [];
+ this._results = {};
this._providers = [];
- this._registerProvider(new AppDisplay.AppSearchProvider());
this._searchSettings = new Gio.Settings({ schema: SEARCH_PROVIDERS_SCHEMA });
this._searchSettings.connect('changed::disabled', Lang.bind(this, this._reloadRemoteProviders));
this._searchSettings.connect('changed::disable-external', Lang.bind(this, this._reloadRemoteProviders));
this._searchSettings.connect('changed::sort-order', Lang.bind(this, this._reloadRemoteProviders));
- this._reloadRemoteProviders();
-
+ this._searchTimeoutId = 0;
this._cancellable = new Gio.Cancellable();
+
+ this._registerProvider(new AppDisplay.AppSearchProvider());
+ this._reloadRemoteProviders();
},
_reloadRemoteProviders: function() {
this._updateResults(provider, results);
},
- setTerms: function(terms) {
+ _doSearch: function() {
this._startingSearch = false;
+ let previousResults = this._results;
+ this._results = {};
+
+ this._providers.forEach(Lang.bind(this, function(provider) {
+ provider.searchInProgress = true;
+
+ let previousProviderResults = previousResults[provider.id];
+ if (this._isSubSearch && previousProviderResults)
+ provider.getSubsearchResultSet(previousProviderResults, this._terms, Lang.bind(this, this._gotResults, provider), this._cancellable);
+ else
+ provider.getInitialResultSet(this._terms, Lang.bind(this, this._gotResults, provider), this._cancellable);
+ }));
+
+ this._updateSearchProgress();
+
+ this._searchTimeoutId = 0;
+ return GLib.SOURCE_REMOVE;
+ },
+
+ setTerms: function(terms) {
+ this._startingSearch = true;
+
this._cancellable.cancel();
this._cancellable.reset();
- if (!terms)
+ if (!terms) {
+ if (this._searchTimeoutId > 0)
+ GLib.source_remove(this._searchTimeoutId);
return;
+ }
let searchString = terms.join(' ');
let previousSearchString = this._terms.join(' ');
isSubSearch = searchString.indexOf(previousSearchString) == 0;
this._terms = terms;
- this._results = {};
-
- this._providers.forEach(Lang.bind(this, function(provider) {
- provider.searchInProgress = true;
-
- let previousProviderResults = previousResults[provider.id];
- if (isSubSearch && previousProviderResults)
- provider.getSubsearchResultSet(previousProviderResults, terms, Lang.bind(this, this._gotResults, provider), this._cancellable);
- else
- provider.getInitialResultSet(terms, Lang.bind(this, this._gotResults, provider), this._cancellable);
- }));
-
+ this._isSubSearch = isSubSearch;
this._updateSearchProgress();
+
+ if (this._searchTimeoutId == 0)
+ this._searchTimeoutId = GLib.timeout_add(GLib.PRIORITY_DEFAULT, 150, Lang.bind(this, this._doSearch));
},
_onPan: function(action) {
});
},
- reset: function() {
- this._terms = [];
- this._results = {};
- this._clearDisplay();
- this._defaultResult = null;
- this._startingSearch = false;
-
- this._updateSearchProgress();
- },
-
- startingSearch: function() {
- this.reset();
-
- // We don't call setTerms and do the actual search until
- // a timeout a little while later, but we don't want to
- // show "No Results" because we think there's no work
- // being done, so we keep this flag to know that there's
- // "pending work". This is cleared in setTerms.
- this._startingSearch = true;
-
- this._updateSearchProgress();
- },
-
_maybeSetInitialSelection: function() {
let newDefaultResult = null;
},
activateDefault: function() {
+ this._doSearch();
+
if (this._defaultResult)
this._defaultResult.activate();
},
this._activePage = null;
this._searchActive = false;
- this._searchTimeoutId = 0;
this._entry = searchEntry;
ShellEntry.addContextMenu(this._entry);
_onTextChanged: function (se, prop) {
let terms = getTermsForSearchString(this._entry.get_text());
- let searchPreviouslyActive = this._searchActive;
this._searchActive = (terms.length > 0);
-
- let startSearch = this._searchActive && !searchPreviouslyActive;
- if (startSearch)
- this._searchResults.startingSearch();
+ this._searchResults.setTerms(terms);
if (this._searchActive) {
+ this._showPage(this._searchPage);
+
this._entry.set_secondary_icon(this._clearIcon);
if (this._iconClickedId == 0)
this._iconClickedId = this._entry.connect('secondary-icon-clicked',
Lang.bind(this, this.reset));
-
- if (this._searchTimeoutId == 0) {
- this._searchTimeoutId = Mainloop.timeout_add(150,
- Lang.bind(this, this._doSearch));
- GLib.Source.set_name_by_id(this._searchTimeoutId, '[gnome-shell] this._doSearch');
- }
} else {
if (this._iconClickedId > 0) {
this._entry.disconnect(this._iconClickedId);
this._iconClickedId = 0;
}
- if (this._searchTimeoutId > 0) {
- Mainloop.source_remove(this._searchTimeoutId);
- this._searchTimeoutId = 0;
- }
-
this._entry.set_secondary_icon(null);
this._searchCancelled();
}
this._searchResults.navigateFocus(nextDirection);
return Clutter.EVENT_STOP;
} else if (symbol == Clutter.Return || symbol == Clutter.KP_Enter) {
- // We can't connect to 'activate' here because search providers
- // might want to do something with the modifiers in activateDefault.
- if (this._searchTimeoutId > 0) {
- Mainloop.source_remove(this._searchTimeoutId);
- this._doSearch();
- }
this._searchResults.activateDefault();
return Clutter.EVENT_STOP;
}
return Clutter.EVENT_PROPAGATE;
},
- _doSearch: function () {
- this._searchTimeoutId = 0;
-
- let terms = getTermsForSearchString(this._entry.get_text());
-
- this._searchResults.setTerms(terms);
- this._showPage(this._searchPage);
-
- return GLib.SOURCE_REMOVE;
- },
-
getActivePage: function() {
if (this._activePage == this._workspacesPage)
return ViewPage.WINDOWS;